<template>
	<view class="o-input" :style="{width: inputStyle.width}">
		<view class="container" :style="{...inputStyle, width: '100%'}">
			<!-- 语音键盘切换组件 -->
			<view class="l-prefix">
				<slot name="prefix">
					<view v-if="voice" class="prefix-icon" @click.stop="cutPreIcon">
						<img src="https://lanhu.oss-cn-beijing.aliyuncs.com/SketchPng936928b1b78f40f6c3e87a97d2c36d94d370a87140e7c7fc395d6fa0d4e3d91a"
							style="width: 46rpx;height: 46rpx;" />
					</view>
				</slot>
			</view>
			<!-- 文本输入 -->
			<!-- :style="{paddingBottom:bottomDistance + 'px'}" -->
			<view class="in-box" v-show="preIconKey === 'voice'">
				<editor id="editor" class="ql-container" @ready="readyHandle" @paste="onPaste"
					@click.stop="editorFocus" @input="inputText" @blur="editorBlur" :adjust-position="false"></editor>
				<view class="r-icon" @click.stop="showEmoji">
					<slot name="suffix">
						<img src="https://lanhu.oss-cn-beijing.aliyuncs.com/SketchPng05b291692ecedefd68d5cf7c3f5958f55998b478f77a8a1ec9aeaca07e66e198"
							style="width: 46rpx;height: 46rpx;" />
					</slot>
				</view>
				<!-- 扩展 -->
				<view class="r-icon" @click.stop="showExtendClick" v-show="!inText.text">
					<slot name="suffix">
						<img src="https://lanhu.oss-cn-beijing.aliyuncs.com/SketchPng13a356fae183f30463b303d17f958cfb6c3b162d390319703a086781f81d4421"
							style="width: 46rpx;height: 46rpx;" />
					</slot>
				</view>
				<view class="btn" @click.stop="submit" v-show="inText.text">
					<slot name="r-btn">
						<button class="submit-btn" :class="inText.text || 'no-text-btn'" size="mini"
							type="primary">发送</button>
					</slot>
				</view>
			</view>
			<!-- 语音输入 -->
			<view class="in-box" v-show="preIconKey === 'keyboard'">
				<view class="voice-btn" @longtap="longtapEvent" @touchend="endEvent" @touchcancel="endEvent"
					@touchmove="moveEvent">
					<slot name="voice-btn">按住说话</slot>
				</view>
			</view>
		</view>
		<view v-show="showEmojiBox" class="emoji-box" :style="emojiStyle">
			<o-emoji @click="insertEmoji"></o-emoji>
		</view>
		<view v-show="showExtend" class="extend-box">
			<view class="" @click="chooseImg">
				<img src="" alt="" />
				<text>相册</text>
			</view>
			<view class="" @click="Paipicture">
				<img src="" alt="" />
				<text>拍照</text>
			</view>
			<view class="" @click="callingCard">
				<img src="" alt="" />
				<text>名片</text>
			</view>
		</view>
		<view v-show="sayVoice" class="o-record-overlay">
			<slot name="record-overlay">
				<view class="close-icon" :class="sayVoiceMove.cancel && 'close-icon-cancel'">
					<i class="iconfont icon-cuowu"></i>
				</view>
				<view class="voice-icon">
					<view class="d-icon iconfont icon-yuyin1"></view>
				</view>
				<view class="animate-box" :class="sayVoiceMove.cancel ? 'animate-box-cancel' : ''">
					<span class="start-taste-line">
						<i v-for="index in (sayVoiceMove.cancel ? 5 : 25)" :key="index" :style="{'--i': index + 1}" />
					</span>
				</view>
			</slot>
		</view>
	</view>
</template>

<script>
	// import OEditor from './o-editor/o-editor.vue';
	import oEmoji from './o-emoji/o-emoji.vue';
	import record from './utils/record';
	import {
		parseToText,
		parseToHtml
	} from './utils/util';
	const plug = uni.requireNativePlugin("Html5App-CameraView");
	export default {
		components: {
			oEmoji,
			// OEditor
		},
		name: "o-input",
		data() {
			return {
				showEmojiBox: false,
				showExtend: false,
				inText: {},
				preIconKey: "voice",
				sayVoice: false,
				sayVoiceMove: {
					x: 0,
					cancel: false,
				},
				prefixIcon: ['voice', 'keyboard'],
				recordInterval: {
					fun: null,
					time: 0,
					timeout: false,
				},
				bottomDistance: 0
			};
		},
		mounted() {
			if (!this.voice) {
				this.preIconKey = "voice";
			}
			if (!(typeof this.maxRecordLen === 'number')) {
				this.maxRecordLen = 59;
			}

		},
		methods: {
			chooseImg() {
				this.$Router.push({
					name: 'chumimage'
				});
			},
			Paipicture() {
				plug.open({
					setMaxduration: 30,
					camera: "back"
				}, retult => {
					if(retult.result == 'success'){
						this.$emit('cameracall',retult)
					}
				});
			},
			callingCard(){
				this.$Router.push({
					name: 'business_share',
					params: {
						type:'card',
					}
				});
			},
			hidedKeyboard() {
				if (this.showEmojiBox) {
					this.showEmojiBox = false
				}
				if (this.showExtend) {
					this.showExtend = false
				}
			},
			showEmoji() {
				setTimeout(() => {
					this.showEmojiBox = !this.showEmojiBox;
					if (this.showEmojiBox) {
						this.showExtend = false
					}
				}, 100)
			},
			showExtendClick() {
				setTimeout(() => {
					this.showExtend = !this.showExtend;
					if (this.showExtend) {
						this.showEmojiBox = false
					}
				}, 100)
			},
			insertEmoji(emoji) {
				this.$emit("clickEmoji", emoji);
				this.showEmojiBox = false;
				this.editorCtx.insertImage({
					src: emoji.src,
					width: this.eSize,
					height: this.eSize,
					extClass: 'emoji',
					data: {
						name: emoji.regName
					}
				})
			},
			onPaste(e){
				console.log(e);
			},
			submit() {
				if (!this.inText?.text) return;
				let detail = {
					...this.inText
				};
				detail.html = parseToHtml(detail.text);
				this.$emit("change", detail);
				this.editorCtx.clear();
			},
			inputText(e) {
				this.getContents().then(res => {
					this.inText = res;
					this.$emit("input", this.inText.text)
				})
			},
			getContents() {
				return new Promise((resolve) => {
					this.editorCtx.getContents({
						success: (res) => {
							let inText = parseToText(res.html);
							resolve(inText)
						}
					})
				})
			},
			editorFocus(e) {
				if (this.showEmojiBox) {
					this.showEmojiBox = false
				}
				if (this.showExtend) {
					this.showExtend = false
				}
			},
			editorBlur() {

			},
			cutPreIcon() {
				let key = this.prefixIcon.filter(val => val != this.preIconKey);
				this.preIconKey = key[0];
				if (this.preIconKey == 'keyboard') {
					this.showEmojiBox = false;
					if (this.showExtend) {
						this.showExtend = false
					}
				}
				this.$emit("cut-mode", key);
			},
			longtapEvent(e) {
				this.sayVoiceMove.x = e.touches[0].pageY;
				this.sayVoice = true;
				record.start();
				this.recordInterval.fun = setInterval(() => {
					if (this.recordInterval.time >= this.maxRecordLen) {
						clearInterval(this.recordInterval.fun);
						this.endEvent();
						this.recordInterval.timeout = true;
					}
					this.recordInterval.time++;
				}, 1000);
			},
			moveEvent(e) {
				if (this.sayVoiceMove.x - e.touches[0].pageY > this.offsetY) {
					this.sayVoiceMove.cancel = true;
				} else {
					this.sayVoiceMove.cancel = false;
				}
			},
			async endEvent() {
				if (this.recordInterval.timeout) {
					this.recordInterval.timeout = false;
					return;
				}
				record.stop();
				clearInterval(this.recordInterval.fun);
				try{
					let result = await record.onStop();
				}catch(e){
					console.log(e);
				}
				// let result = await record.onStop();
				let savedFilePath = await this.saveFile(result.tempFilePath);
				if (this.recordInterval.time < this.minRecordLen) {
					uni.showToast({
						title: "语音时长过短",
						icon: 'none',
						duration: 1000
					});
				} else {
					this.$emit("record", {
						cancel: this.sayVoiceMove.cancel,
						duration: this.recordInterval.time,
						result: savedFilePath
					});
				}
				this.sayVoice = false;
				this.sayVoiceMove.cancel = false;
				this.recordInterval.time = 0;
			},
			saveFile(tempFilePath) {
			  return new Promise((resolve, reject) => {
				uni.saveFile({
				  tempFilePath,
				  success: (res) => {
					resolve(res.savedFilePath);
				  },
				  fail: (error) => {
					reject(error);
				  }
				});
			  });
			},

			readyHandle(editor) {
				// this.editorCtx = editor;
				uni.createSelectorQuery().select('#editor').context((res) => {
					this.editorCtx = res.context
				}).exec()
			}
		},
		props: {
			width: {
				type: String,
				default: "750rpx"
			},
			height: {
				type: String,
				default: "30"
			},
			emojiSize: {
				type: String,
				default: "15"
			},
			fontSize: {
				type: Number,
				default: 14
			},
			placeholder: {
				type: String,
				default: '请输入内容'
			},
			emojiStyle: {
				type: Object,
				default: () => {
					return {}
				}
			},
			resize: {
				type: Boolean,
				default: false,
			},
			voice: {
				type: Boolean,
				default: true,
			},
			maxRecordLen: {
				type: Number,
				default: 59
			},
			minRecordLen: {
				type: Number,
				default: 1
			},
			offsetY: {
				type: Number,
				default: 40,
				require: true
			}
		},
		computed: {
			inputStyle() {
				let regx = /[a-zA-Z%]/;
				let style = {
					width: this.width,
					// height: this.height,
					fontSize: this.fontSize + 'px',
					minHeight: this.height,
					lineHeight: this.height
				}
				if (!regx.test(this.width)) {
					style.width = this.width + 'px';
				}
				if (!regx.test(this.height)) {
					// style.height = this.height + 'px';
					style.minHeight = this.height + 'px';
					style.lineHeight = this.height + 'px';
				}
				return style;
			},
			eSize() {
				let regx = /[a-zA-Z%]/;
				if (!regx.test(this.emojiSize)) {
					return this.emojiSize + 'px';
				}
				return this.emojiSize
			}
		},
	};
</script>

<style lang='scss' scoped>
	.o-input {
		width: 750rpx;
		display: flex;
		flex-direction: column;
		background-color: #ededed;
		padding: 20rpx 30rpx;
		box-sizing: border-box;

		.container {
			display: flex;
			align-items: center;

			.l-prefix {
				height: 100%;

				.prefix-icon {
					display: flex;
					justify-content: center;
					align-items: center;
					margin-right: 20rpx;
				}
			}

			.in-box {
				flex: 1;
				box-sizing: border-box;
				display: flex;
				align-items: center;
				max-height: inherit;

				.ql-container {
					flex: 1;
					font-size: inherit;
					display: block;
					height: inherit;
					min-height: inherit;
					padding: 20rpx 20rpx;
					border-radius: 20rpx;
					outline: none;
					line-height: 1.2;
					background-color: #ffffff;

					/* ::v-deep p {
						display: flex;
						align-items: center;
						height: inherit;
					} */
				}

				.r-icon {
					display: flex;
					align-items: center;
					margin: 0 0 0 20rpx;
				}

				.btn {
					height: inherit;
					padding: 5rpx;
					margin-left: 20rpx;

					.submit-btn {
						height: 100%;
						width: 45px;
						font-size: 10px;
						border-radius: 0;
						border: none;
						padding: 0;
						display: flex;
						align-items: center;
						justify-content: center;
						color: white;

						&::after {
							border: none;
						}

						&:active {
							background-color: green;
						}
					}

					.no-text-btn {
						background-color: rgb(228, 228, 228);
						background-color: red;
						color: black;

						&:active {
							background-color: rgb(228, 228, 228);
							background-color: red;
						}
					}
				}

				// 语音输入框
				.voice-btn {
					display: flex;
					align-items: center;
					justify-content: center;
					flex: 1;
					height: 74rpx;
					background: #ffffff;
					border-radius: 20rpx;

					&:active {
						/* background-color: #97ec6a; */
						/* background-color: rgb(177, 174, 195); */
						background-color: #2e304b;
						color: white;
					}
				}
			}
		}

		.emoji-box {
			width: 100%;
		}

		.extend-box {
			width: 100%;
			display: flex;
			flex-wrap: wrap;
			padding: 100rpx 50rpx;
			gap: 50rpx;
		}

		.o-record-overlay {
			height: 100vh;
			width: 100vw;
			position: fixed;
			top: 0;
			left: 0;
			z-index: 100;
			background-color: rgba($color: #474747, $alpha: .95);

			.close-icon {
				transition: all .5s;
				display: flex;
				justify-content: center;
				align-items: center;
				position: absolute;
				bottom: 100px;
				left: 50px;
				width: 50px;
				height: 50px;
				line-height: 50px;
				text-align: center;
				font-size: 30px;
				border-radius: 50%;
				background-color: #393939;
				color: #9c9c9c;

				i {
					font-style: normal;
					font-size: 20px;
					transform: rotate(-20deg);
				}
			}

			.close-icon-cancel {
				/* background-color: white; */
				background-color: red;
				color: black;
				transform: scale(1.5);

				&::before {
					content: "松开 取消";
					color: #a0a0a0;
					position: absolute;
					top: -35px;
					left: -15px;
					font-size: 8px;
					width: 80px;
					border-radius: 0;
				}
			}

			.voice-icon {
				display: flex;
				justify-content: center;
				width: 180%;
				height: 60%;
				position: absolute;
				bottom: -50%;
				left: -40%;
				border-radius: 50%;
				background-color: #3a3a3a;

				.d-icon {
					margin-top: 25px;
					font-size: 20px;
					color: #aaa;
				}
			}

			.animate-box {
				transition: all .3s;
				position: absolute;
				bottom: 40%;
				left: 50%;
				width: 120px;
				height: 60px;
				padding: 0;
				display: flex;
				align-items: center;
				justify-content: center;
				border-radius: 15px;
				transform: translateX(-50%);
				background-color: #97ec6a;

				.start-taste-line {
					display: flex;

					i {
						background-color: black; //声波颜色
						width: 1px;
						height: 4px;
						margin: 0 1px;
						display: block;
						border: none;
						animation: note 0.2s ease-in-out;
						animation-iteration-count: infinite;
						animation-direction: alternate;
						animation-delay: calc(-0.1s * var(--i));

						@keyframes note {
							from {
								transform: scaleY(1);
							}

							to {
								transform: scaleY(4);
							}
						}
					}
				}

				&::after {
					content: "";
					width: 15px;
					height: 15px;
					position: absolute;
					bottom: -5px;
					background-color: inherit;
					transform: rotate(45deg);
				}
			}

			.animate-box-cancel {
				box-sizing: border-box;
				width: 80px;
				left: 35px;
				transform: translateX(0);
				bottom: 200px;
				background-color: #fb5353;

				&::after {
					background-color: #fb5353;
				}
			}
		}
	}
</style>